﻿using System;
using System.Data;
using System.Text;
using RpcHelper;

namespace SqlExecHelper
{
        internal class SqlHelper
        {
                [ThreadStatic]
                public static int RowNum = 0;
                public static T[] GetTable<T> (ISqlBasic sql, IDAL myDAL)
                {
                        StringBuilder str = sql.GenerateSql (out IDataParameter[] param);
                        DataTable table = myDAL.GetDataTable (str.ToString (), param);
                        return ModelHelper.GetModelByTable<T> (table);
                }

                public static int ExecuteNonQuery (ISqlBasic sql, IDAL myDAL)
                {
                        StringBuilder str = sql.GenerateSql (out IDataParameter[] param);
                        SqlHelper.RowNum = myDAL.ExecuteNonQuery (str.ToString (), param);
                        return SqlHelper.RowNum;
                }
                public static int ExecuteNonQuery (string sql, IDAL myDAL, IDataParameter[] param)
                {
                        SqlHelper.RowNum = myDAL.ExecuteNonQuery (sql, param);
                        return SqlHelper.RowNum;
                }

                public static T GetRow<T> (ISqlBasic sql, IDAL myDAL)
                {
                        StringBuilder str = sql.GenerateSql (out IDataParameter[] param);
                        DataRow row = myDAL.GetDataRow (str.ToString (), param);
                        return ModelHelper.GetModelByRow<T> (row);
                }

                #region 单条插入
                public static void Insert (ISqlBasic sql, IDAL myDAL,out long id)
                {
                        StringBuilder str = sql.GenerateSql (out IDataParameter[] param);
                        if (myDAL.ExecuteNonQuery (str.ToString (), param) > 0)
                        {
                                id = Convert.ToInt64 (param[param.Length - 1].Value);
                                return;
                        }
                        throw new ErrorException ("sql.insert.fail");
                }

                public static void Insert (ISqlBasic sql, IDAL myDAL,out int id)
                {
                        StringBuilder str = sql.GenerateSql (out IDataParameter[] param);
                        if (myDAL.ExecuteNonQuery (str.ToString (), param) > 0)
                        {
                                id= Convert.ToInt32 (param[param.Length - 1].Value);
                                return;
                        }
                        throw new ErrorException ("sql.insert.fail");
                }
                #endregion

                #region 批量插入

                public static void BatchInsert (ISqlBasic sql, IDAL myDAL,out int[] ids)
                {
                        StringBuilder str = sql.GenerateSql (out IDataParameter[] param);
                        DataTable table = myDAL.GetDataTable (str.ToString (), param);
                       ids = new int[table.Rows.Count];
                        for (int i = 0; i < ids.Length; i++)
                        {
                                ids[i] = Convert.ToInt32 (table.Rows[i]);
                        }
                }
                public static void BatchInsert (ISqlBasic sql, IDAL myDAL,out long[] ids)
                {
                        StringBuilder str = sql.GenerateSql (out IDataParameter[] param);
                        DataTable table = myDAL.GetDataTable (str.ToString (), param);
                         ids = new long[table.Rows.Count];
                        for (int i = 0; i < ids.Length; i++)
                        {
                                ids[i] = Convert.ToInt64 (table.Rows[i]);
                        }
                }
                #endregion
                public static T[] Query<T> (ISqlBasic sql, IDAL myDAL, out long count)
                {
                        StringBuilder str = sql.GenerateSql (out IDataParameter[] param);
                        DataTable table = myDAL.GetDataTable (str.ToString (), param);
                        object val = param[param.Length - 1].Value;
                        count = val == DBNull.Value ? 0 : Convert.ToInt64 (val);
                        return ModelHelper.GetModelByTable<T> (table); ;
                }
                public static object ExecuteScalar (ISqlBasic sql, IDAL myDAL)
                {
                        StringBuilder str = sql.GenerateSql (out IDataParameter[] param);
                        return myDAL.ExecuteScalar (str.ToString (), param);
                }
                public static T ExecuteScalar<T> (ISqlBasic sql, IDAL myDAL)
                {
                        object val = ExecuteScalar (sql, myDAL);
                        return ModelHelper.GetValue<T> (val);
                }
                public static T ExecuteScalar<T> (ISqlBasic sql, IDAL myDAL, T def)
                {
                        object val = ExecuteScalar (sql, myDAL);
                        if (val == null)
                        {
                                return def;
                        }
                        else
                        {
                                return ModelHelper.GetValue<T> (val);
                        }
                }

                internal static T[] BatchQuery<T> (ISqlBasic sql, IDAL myDAL, out long count)
                {
                        StringBuilder str = sql.GenerateSql (out IDataParameter[] param);
                        DataTable table = myDAL.GetDataTable (str.ToString (), param);
                        count = Convert.ToInt64 (table.Rows[0][0]);
                        if (count == 0 || !Convert.ToBoolean (table.Rows[0][1]))
                        {
                                return Array.Empty<T>();
                        }
                        return ModelHelper.GetModelByTable<T> (table);
                }
        }
}
